/*
 * SwingCanvas.java
 *
 * Created on 11 maj 2007, 15:10
 */

package edu.uj.petri.gui;

import edu.uj.petri.common.Settings;
import edu.uj.petri.view.Canvas;
import java.awt.*;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.util.*;
import javax.swing.JPanel;

/**
 * Canvas painting on a Swing object.
 *
 * <p>Class counts point coordinates in "units" (two kinds: Unit - for lines,
 * circles etc., and FontUnit - for text). So, when you say "write a line
 * 3.5 unit long" would draw line of length 14 pixels when Unit had been
 * set to 4.0 [pixels] and would draw line of length 70 pixels when Unit had
 * been set to 20.0 [pixels].</p>
 * @author Lukasz
 */
public class SwingCanvas implements Canvas {
    
    private double unitInPixels;
    private double fontUnitInPixels;
    
    private int valueXinUnits,valueYinUnits, valueWIDTHinUnits, valueHEIGHTinUnits;
    private int valueFONTSIZEinUnits;
    
    private Graphics componentGraphics;
    private JPanel component;
    
    /**
     * Creates a new instance of SwingCanvas
     * @param unit unit (in pixels)
     * @param fontUnit font unit (in pixels)
     */
    public SwingCanvas(JPanel component, double unit, double fontUnit) {
        // made by MonikaG: component is something on what you can draw
        // TODO take a Swing object (JDrawPane?)
        this.unitInPixels = unit;
        this.fontUnitInPixels = fontUnit;
        this.componentGraphics = component.getGraphics();
        this.component = component;
    }
    
    /**
     * converts point from screen coorinates (in pixels) to canvas
     * coordinates (in units)
     */
    public Point2D convertScreenToCanvas( int x, int y) {
        //TODO: calculate
        return new Point2D.Double( x*unitInPixels, y*unitInPixels);
    }
    
    public Point convertCanvasToScreen( double x, double y) {
        //TODO: calculate
        return new Point( (int)(x/unitInPixels), (int)(y/unitInPixels));
    }
    
    public Component getComponent() {
        return component;
    }
    
    /**
     * calculates unit values for shapes (apart from text and line) based on coordinates got
     * from rectangle and on unitInPixelsUnits
     */
    private void calculateCanvasShapeUnits(java.awt.geom.Rectangle2D rectangle){
        valueXinUnits = (int)(rectangle.getX()/unitInPixels);
        valueYinUnits = (int)(rectangle.getY()/unitInPixels);
        valueWIDTHinUnits = (int)(rectangle.getWidth()/unitInPixels);
        valueHEIGHTinUnits = (int)(rectangle.getHeight()/unitInPixels);
    }
    
    
    
    /**
     * calculates unit values for  text based on coordinates got
     * from rectangle and on fontUnitInPixels
     */
    private void calculateCanvasTextUnits(java.awt.geom.Rectangle2D rectangle){
        //TODO:
    }
    
    
    public void drawLine(double x1,double y1,double x2, double y2, java.awt.Color color) {
        
        if (componentGraphics == null) componentGraphics = getGraphicsFromComponent();
        
        int valueX1, valueX2, valueY1, valueY2;
        valueX1 = (int)(x1/unitInPixels);
        valueY1 = (int)(y1/unitInPixels);
        valueX2 = (int)(x2/unitInPixels);
        valueY2 = (int)(y2/unitInPixels);
        
        componentGraphics.setColor(color);
        componentGraphics.drawLine(valueX1,valueY1,valueX2,valueY2);
    }
    
    public void drawPolygon( java.util.List<Point2D> points) {
        if (componentGraphics == null) componentGraphics = getGraphicsFromComponent();
        
        Polygon polygon = new Polygon();
        
        for (Point2D p : points) {
            Point translated = convertCanvasToScreen( p.getX(), p.getY() );
            polygon.addPoint( (int)translated.getX(), (int)translated.getY() );
        }
        
        componentGraphics.fillPolygon( polygon );
        
    }
    
    public void drawCircle(java.awt.geom.Rectangle2D rectangle, java.awt.Color color, boolean filled) {
        
        if (componentGraphics == null) componentGraphics = getGraphicsFromComponent();
        
        calculateCanvasShapeUnits(rectangle);
        
        if (filled){
            componentGraphics.setColor(color);
            componentGraphics.fillOval(valueXinUnits,valueYinUnits,valueWIDTHinUnits,valueHEIGHTinUnits);
        }else{
            componentGraphics.setColor(Color.WHITE);
            componentGraphics.fillOval(valueXinUnits,valueYinUnits,valueWIDTHinUnits,valueHEIGHTinUnits);
            componentGraphics.setColor(color);
            componentGraphics.drawOval(valueXinUnits,valueYinUnits,valueWIDTHinUnits,valueHEIGHTinUnits);
        }
    }
    
    public void drawRectangle(java.awt.geom.Rectangle2D rectangle, java.awt.Color color,boolean filled){
        
        if (componentGraphics == null) componentGraphics = getGraphicsFromComponent();
        
        calculateCanvasShapeUnits(rectangle);
        componentGraphics.setColor(color);
        if (filled){
            componentGraphics.fillRect(valueXinUnits,valueYinUnits,valueWIDTHinUnits,valueHEIGHTinUnits);
        }else{
            componentGraphics.drawRect(valueXinUnits,valueYinUnits,valueWIDTHinUnits,valueHEIGHTinUnits);
        }
    }
    
    public void drawRectangle(java.awt.geom.Rectangle2D rectangle, java.awt.Color color) {
        
        if (componentGraphics == null) componentGraphics = getGraphicsFromComponent();
        
        calculateCanvasShapeUnits(rectangle);
        componentGraphics.setColor(color);
        componentGraphics.fillRect(valueXinUnits,valueYinUnits,valueWIDTHinUnits,valueHEIGHTinUnits);
    }
    
    public void drawText(String s, Point2D position) {
        
        if (componentGraphics == null) componentGraphics = getGraphicsFromComponent();
        
        int valueX, valueY;
        valueX = (int)(position.getX()/unitInPixels);
        valueY = (int)(position.getY()/unitInPixels);
        Font f = new Font("SansSerif",1,10); //TODO: set appriopriate Font Size
        componentGraphics.setFont(f);
        componentGraphics.drawString(s,valueX,valueY);
        //TODO: font size needs to be set
    }
    
    public Dimension2D getTextSize(String s) {
        return null; // TODO implement
    }
    
    
    public void clear() {
        if (componentGraphics != null) {
            Dimension dim = component.getSize();
            componentGraphics.setColor(Color.WHITE);
            componentGraphics.fillRect(0,0,(int)dim.getWidth(),(int)dim.getHeight());
        }
    }
    
    private Graphics getGraphicsFromComponent() {
        Settings settings = Settings.getInstance();
        
        Graphics2D retval = (Graphics2D)component.getGraphics();
        if (settings.getUseAntialiasing()) {
            retval.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
        }
        return retval;
    }
    
    
}
